home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / emulation / c64gfx / src / foxtoppm.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  6KB  |  268 lines

  1. /************************************************************************\
  2. * C64 printfox to portable pixmap converter 2-May-93                     *
  3. * By Pasi 'Albert' Ojala (c) 1991-1998                                   *
  4. *    albert@cs.tut.fi  albert@cc.tut.fi                                  *
  5. *                                                                        *
  6. * 22-Jan-95 TABsize=8, cleaning up                                       *
  7. *                                                                        *
  8. * PageFox format by Nicolas Welte 06-Jul-1998                            *
  9. *    welte@chemie.uni-konstanz.de                                        *
  10. *                                                                        *
  11. * 21-Jul-98 Reformatting and cleaning up of the source code              *
  12. *           Also, reduced memory consumption and added '-m' flag  -Pasi  *
  13. *                                                                        *
  14. \************************************************************************/
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20. typedef unsigned char UBYTE;
  21.  
  22. char *vers="\0$VER: foxtoppm 1.3 22-Jul-98\n";
  23.  
  24. #define TABLESIZE    65000
  25.  
  26. static UBYTE gfxmem[TABLESIZE];
  27. static int width, height, mode;
  28. static int flags = 0;
  29.  
  30. void Convert(char *name);
  31.  
  32. #define F_MULTI    (1<<0)
  33. #define F_ERROR    (1<<7)
  34.  
  35.  
  36. int main(int argc, char *argv[]) {
  37.     int i, pointer = 0, repeats, c, size = 0;
  38.     char *inFile = NULL, *outFile = NULL;
  39.     FILE *inFp;
  40.  
  41.     for (i=1; i<argc; i++) {
  42.     if (argv[i][0]=='-') {
  43.         for (c=1; argv[i][c]; c++) {
  44.         switch (argv[i][c]) {
  45.         case 'm':
  46.             flags |= F_MULTI;
  47.             break;
  48.         default:
  49.             flags |= F_ERROR;
  50.         }
  51.         }
  52.     } else {
  53.         if (!inFile) {
  54.         inFile = argv[i];
  55.         } else if (!outFile) {
  56.         outFile = argv[i];
  57.         } else {
  58.         flags |= F_ERROR;
  59.         }
  60.     }
  61.     }
  62.     if ((flags & F_ERROR)) {
  63.     fprintf(stderr, "\n%s", vers+7);
  64.     fprintf(stderr, "Usage: %s [-m] [printfoxfile] [ppmfile]\n", argv[0]);
  65.     fprintf(stderr, "       m - force multicolor mode\n");
  66.     exit(10);
  67.     return EXIT_FAILURE;
  68.     }
  69.  
  70.     if (inFile) {
  71.     inFp = fopen(inFile, "rb");
  72.     if (!inFp) {
  73.         fprintf(stderr, "Could not open %s for reading\n", inFile);
  74.         return EXIT_FAILURE;
  75.     }
  76.     } else {
  77.     inFp = stdin;
  78.     }
  79.  
  80.     mode = fgetc(inFp);
  81.     size++;
  82.     if (mode == EOF) {
  83.     fprintf(stderr,
  84.         "Unexpected EOF while reading file type\n");
  85.     if (inFp != stdin)
  86.         fclose(inFp);
  87.     return EXIT_FAILURE;
  88.     }
  89.  
  90.     switch (mode) {
  91.     case 0x50:
  92.     height = fgetc(inFp);
  93.     width  = fgetc(inFp);
  94.     size += 2;
  95.     if (height == EOF || width == EOF) {
  96.         fprintf(stderr,
  97.             "Unexpected EOF while reading picture size\n");
  98.         if (inFp != stdin)
  99.         fclose(inFp);
  100.         return EXIT_FAILURE;
  101.     }
  102.     c = 2 + height*4;       /* skip ID and outline info */
  103.     size += 2 + height*4;
  104.     while (c--) {
  105.         (void)fgetc(inFp);
  106.     }
  107.     fprintf(stderr, "PG (short RLE) %d(w) x %d(h)\n", width, height);
  108.     break;
  109.     case 0x47:
  110.     width  = 80;
  111.     height = 50;
  112.     fprintf(stderr, "GB (long RLE) %d(w) x %d(h)\n", width, height);
  113.     break;
  114.     case 0x42:
  115.     width  = 40;
  116.     height = 25;
  117.     fprintf(stderr, "BS %s(single screen) %d(w) x %d(h)\n",
  118.         (flags & F_MULTI)?"multicolor ":"",
  119.         width, height);
  120.     break;
  121.     case 0x01:
  122.     width  = 40;
  123.     height = 25;
  124.     fprintf(stderr, "Uncompressed %s%d(w) x %d(h)\n",
  125.         (flags & F_MULTI)?"multicolor ":"",
  126.         width, height);
  127.     break;
  128.     default:
  129.     fprintf(stderr, "ID not recognized (%d)\n", mode);
  130.     if (inFp != stdin)
  131.         fclose(inFp);
  132.     return EXIT_FAILURE;
  133.     }
  134.     if (mode==0x01) {
  135.     /* Uncompressed */
  136.     for (i=0; i<8000; i++) {
  137.         gfxmem[i] = (c = fgetc(inFp));
  138.         if (c == EOF) {
  139.         fprintf(stderr,
  140.             "Unexpected EOF while reading graphics data\n");
  141.         break;
  142.         }
  143.     }
  144.     if (inFp != stdin)
  145.         fclose(inFp);
  146.     Convert(outFile);
  147.     return 0;
  148.     }
  149.  
  150.     /* 0x50 PG(short RLE) 0x47 GB(long RLE), 0x42 small (printfox) */
  151.     while (pointer < TABLESIZE) {
  152.     c = fgetc(inFp);
  153.     if (c == EOF)
  154.         break;
  155.     size++;
  156.     if (c == 0x9b) {
  157.         /* Repeat */
  158.         c = fgetc(inFp);
  159.         if (c == EOF)
  160.         break;
  161.         size++;
  162.         repeats = c;
  163.         if (mode == 0x50) {
  164.         if (repeats == 0)
  165.             repeats = 256;
  166.         } else {
  167.         c = fgetc(inFp);
  168.         if (c == EOF)
  169.             break;
  170.         size++;
  171.         repeats += c*256;
  172.         }
  173.         c = fgetc(inFp);
  174.         if (c == EOF)
  175.         break;
  176.         size++;
  177.         while (repeats--) {
  178.         if (pointer<0 || pointer>=TABLESIZE) {
  179.             fprintf(stderr,
  180.                 "Pixel table overrun: %d\n",
  181.                 pointer);
  182.             break;
  183.         }
  184.         gfxmem[pointer++] = c;
  185.         }
  186.     } else {
  187.         gfxmem[pointer++] = c;
  188.     }
  189.     }
  190.     c = fgetc(inFp);
  191.     if (c != EOF) {
  192.     fprintf(stderr, "Extra bytes in the input file\n");
  193.     }
  194.     if (inFp != stdin)
  195.     fclose(inFp);
  196.     fprintf(stderr, "%d bytes compressed, %d uncompressed\n",
  197.         size, pointer);
  198.     Convert(outFile);
  199.     return 0;
  200. }
  201.  
  202.  
  203. void Convert(char *name) {
  204.     int x,y,pos,z;
  205.     static const UBYTE bitmask[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
  206.     static const UBYTE bitmask2[4] = {0xc0,0x30,0x0c,0x03};
  207.     FILE *handle;
  208.     UBYTE *buffer = malloc(3*width*8);
  209.  
  210.     if (!buffer) {
  211.     fprintf(stderr, "Could not allocate %d bytes\n", 3*width*8);
  212.     return;
  213.     }
  214.  
  215.     fprintf(stderr,"Converting picture\n");
  216.     if (name) {
  217.     handle = fopen(name, "wb");
  218.     } else {
  219.     handle = stdout;
  220.     }
  221.     if (!handle) {
  222.     fprintf(stderr, "Could not open %s for writing\n", name);
  223.     free(buffer);
  224.     return;
  225.     }
  226.     if ((flags & F_MULTI))
  227.     fprintf(handle,"P6\n%d %d\n255\n", width*4, height*8);
  228.     else
  229.     fprintf(handle,"P6\n%d %d\n255\n", width*8, height*8);
  230.  
  231.     if ((flags & F_MULTI)) {
  232.     for (y=0; y<height*8; y++) {
  233.         for (x=0; x<width*4; x++) {
  234.         pos  = (y%8)+(x/4)*8+(y/8)*320;    /* grafix memory byte */
  235.  
  236.         z = (3-((gfxmem[pos] & bitmask2[x%4])>>((3-x%4)*2)))*255/3;
  237.  
  238.         buffer[3*x]   = z;
  239.         buffer[3*x+1] = z;
  240.         buffer[3*x+2] = z;
  241.         }
  242.         fwrite(buffer, width*4, 3, handle);
  243.     }
  244.     } else {
  245.     for (y=0; y<height*8; y++) {
  246.         for (x=0; x<width*8; x++) {
  247.         pos = (y%8)+(x/8)*8+(y/8)*width*8;    /* grafix memory byte */
  248.  
  249.         if ((gfxmem[pos] & bitmask[x%8])) {
  250.             buffer[3*x]   = 0;
  251.             buffer[3*x+1] = 0;
  252.             buffer[3*x+2] = 0;
  253.         } else {
  254.             buffer[3*x]   = 255;
  255.             buffer[3*x+1] = 255;
  256.             buffer[3*x+2] = 255;
  257.         }
  258.         }
  259.         fwrite(buffer, width*8, 3, handle);
  260.     }
  261.     }
  262.     if (handle != stdout)
  263.     fclose(handle);
  264.     free(buffer);
  265. }
  266.  
  267.  
  268.